package com.example.zhu.service.Impl;

import com.alibaba.fastjson.JSONObject;
import com.example.zhu.config.WxHttpRequest;
import com.example.zhu.config.WxInformation;
import com.example.zhu.config.WxWayJsapi;
import com.example.zhu.utils.HttpRequestHelper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.wechat.pay.contrib.apache.httpclient.exception.HttpCodeException;
import com.wechat.pay.contrib.apache.httpclient.exception.NotFoundException;
import com.wechat.pay.contrib.apache.httpclient.notification.Notification;
import com.wechat.pay.contrib.apache.httpclient.notification.NotificationHandler;
import com.wechat.pay.contrib.apache.httpclient.notification.NotificationRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.util.EntityUtils;

import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;

import java.util.*;



@Slf4j
@Service
public class WxPayService {
    @Resource
    private WxInformation wxInformation;
    @Resource
    private WxWayJsapi wxWayJsapi;
    @Resource
    private WxHttpRequest wxHttpRequest;




    public Boolean refund(String outTradeNo, String out_refund_no, String reason, String amount) throws IOException, GeneralSecurityException, HttpCodeException, NotFoundException {
        //设置微信请求url
        HttpPost httpPost = new HttpPost(wxInformation.getWxUrl().concat(wxWayJsapi.getRefund()));
        httpPost.addHeader("Accept", "application/json");
        httpPost.addHeader("Content-type", "application/json;charset=utf-8");
        // 请求body参数
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectMapper objectMapper = new ObjectMapper();
        ObjectNode rootNode = objectMapper.createObjectNode();
        rootNode.put("out_trade_no", outTradeNo)
                .put("out_refund_no", out_refund_no)
                .put("notify_url", wxInformation.getRefundNotifyUrl())
                .put("reason", reason);
        //总金额，单位为分
        Integer amount1 = Integer.valueOf(amount);

        rootNode.putObject("amount")
                .put("refund", amount1)
                .put("total", amount1)
                .put("currency", "CNY");
        log.info("请求参数 ===> " + rootNode);
        objectMapper.writeValue(bos, rootNode);
        httpPost.setEntity(new StringEntity(bos.toString("UTF-8"), "UTF-8"));
        /**
         * 完成签名并执行请求
         * */
        CloseableHttpResponse response = wxHttpRequest.sendWX(wxHttpRequest.getVerifier()).execute(httpPost);
        int code = response.getStatusLine().getStatusCode();
        if (code == 200) {
            String bodyAsString = EntityUtils.toString(response.getEntity());
            log.info("返回的响应体是 =====》 " + bodyAsString);
            JSONObject bodyobj = JSONObject.parseObject(bodyAsString);
            String ResponseOutRefundNo = (String) bodyobj.get("out_refund_no");
            log.info("退款成功 ，退款单号：" + ResponseOutRefundNo);
            return true;
        }
        String bodyAsString = EntityUtils.toString(response.getEntity());
        log.info("返回的响应体是 =====》 " + bodyAsString);
        return false;
    }

    public Map payRefund(HttpServletRequest request) {
        Map<String, String> result = new HashMap();
        try {
            String requestBody = HttpRequestHelper.getRequestBody(request);
            log.info("退款成功响应数据是： " + requestBody);
            JSONObject requestBodyJson = JSONObject.parseObject(requestBody);
            //微信返回的证书序列号
            String serialNo = request.getHeader("Wechatpay-Serial");
            //微信返回的随机字符串
            String nonceStr = request.getHeader("Wechatpay-Nonce");
            //微信返回的时间戳
            String timestamp = request.getHeader("Wechatpay-Timestamp");
            //微信返回的签名
            String wechatSign = request.getHeader("Wechatpay-Signature");
            // 构建request，传入必要参数
            NotificationRequest request1 = new NotificationRequest.Builder().withSerialNumber(serialNo)
                    .withNonce(nonceStr)
                    .withTimestamp(timestamp)
                    .withSignature(wechatSign)
                    .withBody(requestBody)
                    .build();
            NotificationHandler handler = new NotificationHandler(wxHttpRequest.getVerifier().getVerifier(wxInformation.getMchId()), wxInformation.getV3Key().getBytes(StandardCharsets.UTF_8));
            // 验签和解析请求体
            Notification notification = handler.parse(request1);
            // 从notification中获取解密报文
            log.info("退款成功获取解密报文： " + notification.getDecryptData());
            if (notification.getDecryptData() != null) {
                if ("REFUND.SUCCESS".equals(requestBodyJson.get("event_type") + "")) {
                    JSONObject resourcePayJson = JSONObject.parseObject(notification.getDecryptData());
                    //根据微信之后返回的结果对订单进行不同的处理
                    if ("SUCCESS".equals(resourcePayJson.get("refund_status") + "")) {
                        log.info("订单商户订单号：" + resourcePayJson.get("out_trade_no") + "\t退款成功\t" + "退款金额：" + resourcePayJson.getJSONObject("amount").get("total"));
                    } else {
                        log.info("微信返回支付失败： 失败单号" + resourcePayJson.get("out_trade_no") + "失败状态" + resourcePayJson.get("trade_state"));
                    }
                } else {
                    log.error("微信返回退款错误摘要：" + requestBodyJson.get("summary"));
                }
            }
        } catch (Exception e) {
            result.put("code", "fail");
            result.put("message", "系统错误");
            e.printStackTrace();
        }
        result.put("code", "SUCCESS");
        result.put("message", "成功");
        return result;
    }


}
